package com.ds.home.engine;

import com.alibaba.fastjson.JSONObject;
import com.ds.client.JDSSessionFactory;
import com.ds.command.Command;
import com.ds.common.JDSConstants;
import com.ds.common.JDSException;
import com.ds.common.cache.Cache;
import com.ds.common.cache.CacheManagerFactory;
import com.ds.common.logging.Log;
import com.ds.common.logging.LogFactory;
import com.ds.common.query.Condition;
import com.ds.common.query.JLuceneIndex;
import com.ds.config.ListResultModel;
import com.ds.context.JDSActionContext;
import com.ds.engine.ConnectInfo;
import com.ds.engine.JDSSessionHandle;
import com.ds.enums.MsgStatus;
import com.ds.home.EIDevice;
import com.ds.home.EIDeviceEndPoint;
import com.ds.home.EIPlace;
import com.ds.home.EIZNode;
import com.ds.home.event.DeviceEndPointEvent;
import com.ds.home.event.DeviceEvent;
import com.ds.home.event.SensorEvent;
import com.ds.home.event.ZNodeEvent;
import com.ds.home.proxy.*;
import com.ds.home.query.HomeConditionKey;
import com.ds.home.query.IOTConditionKey;
import com.ds.iot.*;
import com.ds.iot.enums.*;
import com.ds.iot.json.NetworkInfo;
import com.ds.iot.json.SensorInfo;
import com.ds.iot.json.device.Gateway;
import com.ds.iot.json.device.GatewayErrorReport;
import com.ds.jds.core.User;
import com.ds.msg.Msg;
import com.ds.msg.MsgClient;
import com.ds.msg.MsgFactroy;
import com.ds.msg.MsgType;
import com.ds.org.OrgManager;
import com.ds.org.Person;
import com.ds.org.PersonNotFoundException;
import com.ds.server.JDSClientService;
import com.ds.server.JDSServer;
import com.ds.server.OrgManagerFactory;
import com.ds.server.SubSystem;
import com.ds.server.eumus.ConfigCode;
import com.ds.thread.JDSThreadFactory;
import com.ds.thread.ThreadShutdown;
import net.sf.cglib.beans.BeanMap;

import java.util.*;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class AppEngine {

    public String systemCode;

    private GWEngine gwEngine;


    private final Log logger = LogFactory.getLog(HomeConstants.CONFIG_ENGINE_KEY, AppEngine.class);

    // private DataEngine msgEngine;

    private static final Map<String, AppEngine> engineMap = new HashMap<String, AppEngine>();

    private static Cache personIPCache = CacheManagerFactory.createCache(JDSConstants.CONFIG_KEY, "PersonIPCache");

    private static final Map<String, ScheduledExecutorService> threadPoolMap = new HashMap<String, ScheduledExecutorService>();

    private static final Map<String, ScheduledExecutorService> checkTimePoolMap = new HashMap<String, ScheduledExecutorService>();


    private static final Map<String, ScheduledExecutorService> timesPoolMap = new HashMap<String, ScheduledExecutorService>();

    public static Cache getPersonIPCache() {
        return personIPCache;
    }

    public static void setPersonIPCache(final Cache personIPCache) {
        AppEngine.personIPCache = personIPCache;
    }

    private static final Map<String, ScheduledExecutorService> singlePoolMap = new HashMap<String, ScheduledExecutorService>();


    public static ScheduledExecutorService getTimeOutExecutors(final String ieee) {
        ScheduledExecutorService service = timesPoolMap.get(ieee);
        if (service == null || service.isShutdown()) {
//			service = Executors.newScheduledThreadPool(3, new JDSThreadFactory(ieee));
            service = Executors.newScheduledThreadPool(1, new JDSThreadFactory(ieee));
            //service.schedule(new ThreadShutdown(service), 180, TimeUnit.SECONDS);
            timesPoolMap.put(ieee, service);
        }

        return service;
    }

    public static ScheduledExecutorService getCommandExecutors(final String ieee) {
        ScheduledExecutorService service = threadPoolMap.get(ieee);
        if (service == null || service.isShutdown()) {
            service = Executors.newScheduledThreadPool(5, new JDSThreadFactory(ieee));
            service.schedule(new ThreadShutdown(service), 180, TimeUnit.SECONDS);
            threadPoolMap.put(ieee, service);
        }

        return service;
    }

    public SensorInfo updateSensorValue(final String sensorId, final DeviceDataTypeKey attributeName, final String value) throws HomeException {
        final ZNode znode = getZNodeById(sensorId);
        final DeviceEndPointProxy deviceEndPoint = (DeviceEndPointProxy) znode.getEndPoint();
        deviceEndPoint.setCurrvalue(attributeName, value);
        updateEndPoint(deviceEndPoint);
        return new SensorInfo(znode);
    }

    public static ScheduledExecutorService getCommandTimesExecutors(final String ieee) {
        ScheduledExecutorService service = timesPoolMap.get(ieee);
        if (service == null || service.isShutdown()) {
            service = Executors.newSingleThreadScheduledExecutor(new JDSThreadFactory(ieee));
            service.schedule(new ThreadShutdown(service), 180, TimeUnit.SECONDS);
            threadPoolMap.put(ieee, service);
        }

        return service;
    }

    public static ScheduledExecutorService getSingleCommandExecutors(final String ieee) {
        ScheduledExecutorService service = singlePoolMap.get(ieee);
        if (service == null || service.isShutdown()) {
            service = Executors.newScheduledThreadPool(2);
            service.schedule(new ThreadShutdown(service), 90, TimeUnit.SECONDS);
            singlePoolMap.put(ieee, service);
        }

        return service;
    }

    public static AppEngine getEngine(final String systemCode) {
        AppEngine engine = (AppEngine) engineMap.get(systemCode);
        if (engine == null) {
            synchronized (AppEngine.class) {
                engine = new AppEngine(systemCode);
                engineMap.put(systemCode, engine);
            }
        }
        return engine;
    }

    AppEngine(final String systemCode) {
        this.systemCode = systemCode;
        gwEngine = GWEngine.getEngine(systemCode);


    }

    public Area getAreaById(final String areaId) throws HomeException {
        Area area = null;
        if (areaId != null) {
            area = new AreaProxy(gwEngine.getAreaById(areaId), systemCode);
        }

        return area;
    }

    public NetworkInfo changeNetworkResponse(final String gwieee, final NetworkInfo networkInfo) throws HomeException {
        final DeviceProxy device = (DeviceProxy) getDeviceBySerialno(gwieee);
        final DeviceEndPointProxy point = (DeviceEndPointProxy) device.getDeviceEndPoints().get(0);
        point.setCurrvalue(DeviceDataTypeKey.NetworkInfo, JSONObject.toJSONString(networkInfo).toString());
        updateDevice(device);
        return networkInfo;
    }

    public List<Device> getDeviceByChannel(final String channel) throws HomeException {
        final List<Device> devices = new ArrayList<Device>();
        final List<String> deviceIds = gwEngine.getDeviceIdsByChannel(channel);

        for (final String deviceId : deviceIds) {
            Device device = null;
            try {
                device = getDeviceById(deviceId);
                devices.add(device);
            } catch (final HomeException e) {
                e.printStackTrace();
            }

        }
        return devices;
    }

    public Device getDeviceById(final String deviceId) throws HomeException {
        Device device = null;
        if (gwEngine.getDeviceById(deviceId) != null) {
            device = new DeviceProxy(deviceId, systemCode);
        }
        return device;
    }

    public List<Device> getDevicesByArea(final String areaId) throws HomeException {
        final List<Device> devices = new ArrayList<Device>();
        final List<String> eideviceIds = gwEngine.getDevicesIdsByArea(areaId);
        for (final String deviceId : eideviceIds) {
            devices.add(this.getDeviceById(deviceId));
        }
        return devices;
    }


    public Device getDeviceByZNodeId(final String znodeId) throws HomeException {
        Device device = null;
        if (gwEngine.getDeviceByNodeId(znodeId) != null) {
            final String deviceId = gwEngine.getDeviceByNodeId(znodeId).getDeviceid();
            device = getDeviceById(deviceId);
        }
        return device;
    }

    public Device getDeviceBySerialno(final String serialno) throws HomeException {
        final Device device = getDeviceById(gwEngine.getDeviceBySerialno(serialno).getDeviceid());
        return device;
    }

    public List<ZNode> getAllZNodeByDeviceId(final String deviceId, final String personId) throws HomeException {
        final List<ZNode> cznodes = getAllZNodeByDeviceId(deviceId);
        final List<ZNode> znodes = new ArrayList<ZNode>();

        for (final ZNode znode : cznodes) {

            if (znode != null && znode.getCreateuiserid() != null && znode.getCreateuiserid().equals(personId)) {
                znodes.add(znode);
            }

        }
        return znodes;
    }

    public List<ZNode> getAllZNodeByDeviceId(final String deviceId) throws HomeException {
        final List<String> znodeIds = gwEngine.getAllZNodeIdsByDeviceId(deviceId);

        final List<ZNode> znodes = new ArrayList<ZNode>();
        for (final String znodeId : znodeIds) {
            ZNode znode = null;
            try {
                znode = getZNodeById(znodeId);
            } catch (final HomeException e) {
                e.printStackTrace();
            }
            if (znode != null) {
                znodes.add(znode);
            }

        }

        return znodes;
    }

    public List<ZNode> getAllZNodeByEndPointId(final String endPoindId) throws HomeException {
        final List<String> znodeIds = gwEngine.getAllZNodeIdsByEndPointId(endPoindId);

        List<ZNode> znodes = new ArrayList<ZNode>();
        if (znodeIds.isEmpty()) {
            //znodes = reSetZNode(endPoindId);
        } else {
            // 过滤重复值
            final String znodeId = znodeIds.get(0);
            ZNode znode = null;
            try {
                znode = getZNodeById(znodeId);
            } catch (final HomeException e) {
                e.printStackTrace();
            }
            if (znode != null) {
                znodes.add(znode);
            }
        }

        return znodes;
    }

    public void deleteZNode(final String nodeId) throws HomeException {
        gwEngine.deleteNode(nodeId);
    }

    public void deleteDevice(final String deviceId) throws HomeException {
        gwEngine.deleteDevice(deviceId);
    }

    public void clearDevice(final String deviceId) throws HomeException {
        gwEngine.deleteGateway(deviceId);
    }


    public ZNode getZNodeById(final String znodeId) throws HomeException {
        ZNode znode = null;
        if (gwEngine.getZNodeById(znodeId) != null) {
            znode = new ZNodeProxy(gwEngine.getZNodeById(znodeId), getSystemCode());
        }
        return znode;
    }

    public Scene getSceneById(final String id) throws HomeException {
        if (gwEngine.getSceneById(id) != null) {
            return new SceneProxy(gwEngine.getSceneById(id), getSystemCode());
        }
        return null;
    }


    public void updateZNode(final ZNode znode, final boolean indb) throws HomeException {
        ZNodeProxy proxy = (ZNodeProxy) this.getZNodeById(znode.getZnodeid());
        BeanMap realMap = BeanMap.create(znode);
        BeanMap proxyMap = BeanMap.create(proxy);
        proxyMap.putAll(realMap);
        gwEngine.updateZNode(proxy.getZnode(), indb);

    }

    public void updateNodeStatus(final String znodeId, final DeviceStatus status) throws HomeException {
        gwEngine.updateNodeStatus(znodeId, status);
    }

    public Place getPlaceById(final String placeId) throws HomeException {
        Place place = null;
        if (gwEngine.getPlaceById(placeId) != null) {
            place = new PlaceProxy(gwEngine.getPlaceById(placeId), getSystemCode());
        }
        return place;
    }

    public List<Place> getAllPlaceByUserId(final String personId) throws HomeException {
        final List<String> placeIds = gwEngine.getAllPlacesIdByUserId(personId);
        final List<Place> placeInfos = new ArrayList();

        for (final String placeId : placeIds) {
            final Place info = getPlaceById(placeId);
            placeInfos.add(info);
        }

        return placeInfos;
    }

    public List<Place> getAllPlaceByOrgId(final String orgId) throws HomeException {
        final List<String> placeIds = gwEngine.getAllPlacesIdByOrgId(orgId);
        final List<Place> placeInfos = new ArrayList();

        for (final String placeId : placeIds) {
            final Place info = getPlaceById(placeId);
            placeInfos.add(info);
        }

        return placeInfos;
    }

    public List<Place> findAllOrgPlace() throws HomeException {
        final List<String> placeIds = gwEngine.findAllOrgPlaceIds();
        final List<Place> placeInfos = new ArrayList();

        for (final String placeId : placeIds) {
            final Place info = getPlaceById(placeId);
            placeInfos.add(info);
        }

        return placeInfos;
    }

    public List<Place> findAllUserPlace() throws HomeException {
        final List<String> placeIds = gwEngine.findAllPersonPlaceIds();
        final List<Place> placeInfos = new ArrayList();

        for (final String placeId : placeIds) {
            final Place info = getPlaceById(placeId);
            placeInfos.add(info);
        }

        return placeInfos;
    }

    public List<Place> findAllChildPlace() throws HomeException {
        final List<String> placeIds = gwEngine.findAllPersonPlaceIds();
        final List<Place> placeInfos = new ArrayList();

        for (final String placeId : placeIds) {
            final Place info = getPlaceById(placeId);
            placeInfos.add(info);
        }

        return placeInfos;
    }

    public ZNode findZNodeByIeee(final String serialno, final String personId) throws HomeException {
        final DeviceProxy device = (DeviceProxy) getDeviceBySerialno(serialno);
        final List<ZNode> znodes = device.getAllZNodes();

        for (final ZNode znode : znodes) {
            if (znode.getCreateuiserid().equals(personId)) {
                return znode;
            }
        }
        return null;
    }

    public Alarm getAlarmById(final String alarmId) throws HomeException {
        final Alarm alarm = new AlarmProxy(gwEngine.getAlarmById(alarmId), getSystemCode());
        return alarm;
    }

    public List<Area> getAllAreaByPlaceId(final String placeId) throws HomeException {
        final Set<String> areaIds = gwEngine.getAreaIdsByPalceId(placeId);
        final List<Area> areaInfos = new ArrayList<Area>();
        for (final String areaId : areaIds) {
            final Area area = getAreaById(areaId);
            areaInfos.add(area);
        }
        return areaInfos;
    }

    public ZNode findZNodeByDeviceId(final String deviceId, final String personId) throws HomeException {
        final DeviceProxy device = (DeviceProxy) getDeviceById(deviceId);
        final List<ZNode> znodes = device.getAllZNodes();
        ZNode znode = null;
        for (final ZNode childZNode : znodes) {

            if (childZNode.getCreateuiserid().equals(personId)) {
                return getZNodeById(childZNode.getZnodeid());
            }
        }
        if (znodes.size() > 0) {
            znode = znodes.get(0);
        }

        return znode;
    }

    public ZNode findZNodeByEndPointId(final String epId, final String personId) throws HomeException {
        final DeviceEndPoint endPoint = getEndPoint(epId);

        final List<ZNode> znodes = ((DeviceEndPointProxy) endPoint).getAllZNodes();
        final ZNode znode = null;
        for (final ZNode childZNode : znodes) {
            if (childZNode.getCreateuiserid().equals(personId)) {
                getZNodeById(childZNode.getZnodeid());
            }
        }
        return znode;
    }

    // public List<Sensortype> getSensorTypesByGatewayId(String gatewayId)
    // throws HomeException {
    // List<Sensortype> types = new ArrayList<Sensortype>();
    // String batch = this.gwEngine.getDeviceByNodeId(gatewayId).getBatch();
    // if ((batch == null) || (batch.equals(""))) {
    // batch = "default";
    // }
    // List<Integer> sensorTypeIds = this.gwEngine.getSensoTypesByBatch(batch);
    // for (Integer sensorTypeId : sensorTypeIds) {
    //
    // types.add(this.getSensorTypesByNo(sensorTypeId));
    // }
    // return types;
    // }

    public List<Alarm> getAlarmBySensorId(final String sensorId) throws HomeException {
        final List alarms = new ArrayList();
        final List<String> alarmIds = gwEngine.getAlarmIdsBySensorId(sensorId);
        for (final String alarmId : alarmIds) {
            final Alarm alarm = getAlarmById(alarmId);
            alarms.add(alarm);
        }
        return alarms;
    }

    public List<Scene> getSceneBySensorId(final String sensorId) throws HomeException {
        final List<String> sceneIds = gwEngine.getSceneIdsBySensorId(sensorId);
        final List<Scene> sceneinfos = new ArrayList<Scene>();
        for (final String sceneId : sceneIds) {
            sceneinfos.add(getSceneById(sceneId));
        }
        return sceneinfos;
    }

    public Scene geSceneById(final String scenId) throws HomeException {

        return new SceneProxy(gwEngine.getSceneById(scenId), getSystemCode());
    }

    public List<ZNode> getAllChildNodes(final String parentNodeId) throws HomeException {
        final List<String> znodeIds = gwEngine.getAllChildNodeIds(parentNodeId);
        final List<ZNode> znodes = new ArrayList<ZNode>();
        for (final String znodeId : znodeIds) {

            try {
                znodes.add(getZNodeById(znodeId));
            } catch (final HomeException e) {
                e.printStackTrace();
            }

        }
        return znodes;
    }

    public Sensortype getSensorTypesByNo(final Integer typno) throws HomeException {

        return new SensortypeProxy(gwEngine.getSensortypeByNo(typno));
    }

    public String getSystemCodeByIeee(final String serialno) {

        String systemCode = this.systemCode;
        try {

            if (gwEngine.getDeviceBySerialno(serialno) != null) {
                systemCode = gwEngine.getDeviceBySerialno(serialno).getSubsyscode();
            }

        } catch (final HomeException e) {
            e.printStackTrace();
        }
        return systemCode;
    }

    public String getSystemCode() {
        return systemCode;
    }

    // public ZNode createZNode(String endPoint,String parenId, String personId)
    // throws HomeException {
    // String znodeId=this.gwEngine.createZNode(endPoint, parenId,
    // personId).getZnodeid();
    // return this.getZNodeById(znodeId);
    //
    // }
    //

    public Place createPlace(final String name, final String parentId, String userId) throws HomeException {
        final String placeId = gwEngine.createPlace(name, parentId, userId).getPlaceid();
        final Place place = getPlaceById(placeId);

        return place;
    }

    public Alarm creatAlarm(final String sensorId) throws HomeException {
        final String alarmId = gwEngine.creatAlarm(sensorId).getAlarmid();
        return getAlarmById(alarmId);
    }

    public void updateAlarm(final Alarm alarm) throws HomeException {
        Alarm proxy = (Alarm) this.getAlarmById(alarm.getAlarmid());
        BeanMap realMap = BeanMap.create(alarm);
        BeanMap proxyMap = BeanMap.create(proxy);
        proxyMap.putAll(realMap);


        gwEngine.updateAlarm(gwEngine.getAlarmById(alarm.getAlarmid()));

    }

    public void updateDevice(final Device device) throws HomeException {
        updateDevice(device, true);
    }

    public void updateDevice(final Device device, final boolean isindb) throws HomeException {
        DeviceProxy proxy = (DeviceProxy) this.getDeviceById(device.getDeviceid());

        BeanMap realMap = BeanMap.create(device);

        BeanMap proxyMap = BeanMap.create(proxy);

        proxyMap.putAll(realMap);

        gwEngine.updateDevice(proxy.getDbDevice(), isindb);


        for (final DeviceEndPoint endPoint : proxy.getDeviceEndPoints()) {
            updateEndPoint(endPoint, isindb);
        }
        this.fireDeviceEvent(proxy, DeviceEventEnums.deviceActivt);
    }

    public void updateEndPoint(final DeviceEndPoint endPoint) throws HomeException {
        updateEndPoint(endPoint, true);
    }

    public void updateEndPoint(final DeviceEndPoint endPoint, final boolean isindb) throws HomeException {

        DeviceEndPointProxy proxy = (DeviceEndPointProxy) this.getEndPoint(endPoint.getEndPointId());

        BeanMap realMap = BeanMap.create(endPoint);

        BeanMap proxyMap = BeanMap.create(proxy);

        proxyMap.putAll(realMap);

        Map<DeviceDataTypeKey, String> valuemap = endPoint.getCurrvalue();
        Set<DeviceDataTypeKey> keySet = valuemap.keySet();

        for (DeviceDataTypeKey key : keySet) {
            if (key != null && !key.equals("null")) {
                proxy.updateCurrvalue(key, valuemap.get(key));
            }

        }

        gwEngine.updateEndPoint(proxy.getDbEndPoint(), isindb);
        this.fireEndPointEvent(proxy, DeviceEndPointEventEnums.updateInfo);
    }

    public void deleteAlarm(final String alarmId) throws HomeException {
        gwEngine.deleteAlarm(alarmId);
    }

    public void deleteArea(final String areaId) throws HomeException {
        gwEngine.deleteArea(areaId);
    }

    public void deletePlace(final String placeId) throws HomeException {
        gwEngine.deletePlace(placeId);
    }

    public Area createArea(final String name, final String placeId) throws HomeException {
        final String areaId = gwEngine.createArea(name, placeId).getAreaid();
        return getAreaById(areaId);
    }

    public List<Device> getDeviceByBindAccount(final String account) throws HomeException {
        final List<Device> devices = new ArrayList<Device>();
        final List<String> deviceIdList = gwEngine.getDeviceIdsByBindAccount(account);
        for (final String deviceId : deviceIdList) {

            try {
                devices.add(getDeviceById(deviceId));
            } catch (final HomeException e) {
                e.printStackTrace();
            }
        }

        return devices;
    }

    public List<Device> getAllChildDevices(final String parentNodeId) throws HomeException {
        final List<Device> devices = new ArrayList<Device>();

        final Set<String> deviceIdList = gwEngine.getAllChildDeviceIds(parentNodeId);
        for (final String deviceId : deviceIdList) {

            try {
                final Device device = getDeviceById(deviceId);
                if (!devices.contains(device)) {
                    devices.add(device);
                }

            } catch (final HomeException e) {
                // e.printStackTrace();
            }
        }

        return devices;

    }

    public DeviceEndPoint getEndPointSerialno(final String serialno) throws HomeException {
        DeviceEndPoint deviceEndPoint = null;

        if (gwEngine.getEndPointBySerialno(serialno) != null) {
            deviceEndPoint = getEndPoint(gwEngine.getEndPointBySerialno(serialno).getEndPointId());
        }
        return deviceEndPoint;
    }

    public DeviceEndPoint getEndPoint(final String epId) throws HomeException {
        DeviceEndPoint deviceEndPoint = null;
        if (epId != null && gwEngine.getEndPonitById(epId) != null) {
            deviceEndPoint = new DeviceEndPointProxy(gwEngine.getEndPonitById(epId), systemCode);
        }
        return deviceEndPoint;
    }

    public List<DeviceEndPoint> getAllEndPoints(final String deviceId) throws HomeException {
        final List<DeviceEndPoint> epList = new ArrayList<DeviceEndPoint>();

        final List<String> epIdList = gwEngine.getAllEndPointIds(deviceId);
        for (final String epId : epIdList) {
            try {
                DeviceEndPoint deviceEndPoint = getEndPoint(epId);
                if (deviceEndPoint != null) {
                    epList.add(deviceEndPoint);
                }

            } catch (final HomeException e) {
                e.printStackTrace();
            }
        }

        return epList;
    }


    public List<ZNode> getAllZNodeByAreaId(final String areaid) throws HomeException {
        final Set<ZNode> cnodes = new LinkedHashSet<ZNode>();
        List<Device> devices = this.getDevicesByArea(areaid);
        for (Device device : devices) {
            cnodes.addAll(device.getAllZNodes());
        }
        return new ArrayList<>(cnodes);
    }

    public Set<String> getAllZNodeIdsByAreaId(final String areaid) throws HomeException {
        Set<String> nodeIds = new LinkedHashSet<>();
        List<ZNode> zNodes = this.getAllZNodeByAreaId(areaid);
        for (ZNode znode : zNodes) {
            nodeIds.add(znode.getZnodeid());
        }
        return nodeIds;
    }

    public Set<String> getAllZNodeIdsByDeviceId(final String deviceId) throws HomeException {
        Set<String> nodeIds = new LinkedHashSet<>();
        Device device = this.getDeviceById(deviceId);
        List<ZNode> zNodes = device.getAllZNodes();
        for (ZNode znode : zNodes) {
            nodeIds.add(znode.getZnodeid());
        }
        return nodeIds;
    }


    public Set<String> getAllGatewayIdsByPlaceId(final String placeId) throws HomeException {
        Set<String> nodeIds = new LinkedHashSet<>();
        List<String> deviceIds = gwEngine.getGWDevicesByPlaceId(placeId);
        for (String deviceId : deviceIds) {
            nodeIds.addAll(getAllZNodeIdsByDeviceId(deviceId));
        }
        return nodeIds;
    }


    public void updateArea(final Area area) throws HomeException {
        AreaProxy proxy = (AreaProxy) this.getAreaById(area.getAreaid());
        BeanMap realMap = BeanMap.create(area);
        BeanMap proxyMap = BeanMap.create(proxy);
        proxyMap.putAll(realMap);

        gwEngine.updateArea(gwEngine.getAreaById(area.getAreaid()));
    }

    public void updatePlace(final Place place) throws HomeException {
        PlaceProxy proxy = (PlaceProxy) this.getPlaceById(place.getPlaceid());
        BeanMap realMap = BeanMap.create(place);
        BeanMap proxyMap = BeanMap.create(proxy);
        proxyMap.putAll(realMap);

        gwEngine.updatePlace(gwEngine.getPlaceById(place.getPlaceid()));
    }

    public void deleteScene(final String sensorSceneId) throws HomeException {
        gwEngine.deleteScene(sensorSceneId);
    }

    public void updateScene(final Scene scene) throws HomeException {
        SceneProxy proxy = (SceneProxy) this.getSceneById(scene.getSceneid());
        BeanMap realMap = BeanMap.create(scene);
        BeanMap proxyMap = BeanMap.create(proxy);
        proxyMap.putAll(realMap);

        gwEngine.updateScene(gwEngine.getSceneById(scene.getSceneid()));
    }

    public Scene creatScene(final String sensorId) throws HomeException {
        final Scene scene = getSceneById(gwEngine.creatScene(sensorId).getSceneid());
        return scene;
    }

    public List<ZNode> getAllChildNode(final String znodeid) throws HomeException {
        final List<ZNode> childNades = new ArrayList<ZNode>();
        final List<String> childNodeIds = gwEngine.getAllChildNodeIds(znodeid);
        for (final String nodeId : childNodeIds) {
            childNades.add(getZNodeById(nodeId));
        }
        return childNades;
    }

    public List<User> getAllUserByDeviceId(final String deviceid) throws HomeException {

        return gwEngine.getAllUserByDeviceId(deviceid);
    }

    // public ZNode findZNodeGWSerialno(String gwserialno, int sensorType)
    // throws HomeException {
    //
    // return this.getZNodeById(gwEngine.getZNodeGWSerialno(gwserialno,
    // sensorType).getZnodeid());
    // }

    public User getMainUserByDeviceId(final String serialno) throws HomeException {
        return gwEngine.getMainUserByDeviceId(serialno);
    }


    public Device registerGateway(final String deviceid, final String serialno, final String macaddress, final String factoryName, final String version) throws HomeException {

        if (serialno == null || serialno.equals("")) {
            throw new HomeException("serialno is null!");
        }
        final EIDeviceEndPoint endPoint = gwEngine.registerGateway(deviceid, serialno, macaddress, factoryName, version);

        if (endPoint != null && endPoint.getDevice() != null) {
            final Person person = registerPerson(endPoint.getDevice().getDeviceid(), endPoint.getDevice().getSerialno(), factoryName);
        }

        return getDeviceById(endPoint.getDevice().getDeviceid());
    }

    public Device registerDevice(final String serialno, final String gwDeviceId, final Integer deviceType, final String account, final String factoryName) throws HomeException {

        final String deviceId = gwEngine.createDevice(serialno, serialno, deviceType, factoryName, gwDeviceId).getDeviceid();
        Device device = getDeviceById(deviceId);
        fireDeviceEvent(device, DeviceEventEnums.register);
        return device;
    }

    /***
     * 内部调用添加设备
     *
     * @param devices
     * @param gwIeee
     * @throws HomeException
     */
    private void syncSensor(final List<Device> devices, final String gwIeee) throws HomeException {
        final Device gatewaydevice = getDeviceBySerialno(gwIeee);
        Person person = null;
        try {
            person = OrgManagerFactory.getOrgManager().getPersonByAccount(gatewaydevice.getBindingaccount());

        } catch (final PersonNotFoundException e) {
            e.printStackTrace();
            try {
                person = OrgManagerFactory.getOrgManager().getPersonByAccount(gatewaydevice.getAppaccount());
            } catch (final PersonNotFoundException e1) {
                return;
            }
        }

        ZNode gateway = null;
        try {
            gateway = findZNodeByDeviceId(gatewaydevice.getDeviceid(), person.getID());
        } catch (final HomeException e1) {
            registerGateway(gatewaydevice.getDeviceid(), gatewaydevice.getSerialno(), gatewaydevice.getMacaddress(), gatewaydevice.getFactory(), gatewaydevice.getBatch());
        }
        if (gateway == null) {
            gateway = createGateway(gatewaydevice.getSerialno(), person.getID());
        }

        final List<Device> deviceList = getAllChildDevices(gateway.getZnodeid());

        for (final Device device : deviceList) {
            if (device.getFactory() == null) {
                removeDevice(device.getDeviceid());
            } else if (!devices.contains(device) && device.getFactory().equals(gatewaydevice.getFactory())) {
                removeDevice(device.getDeviceid());
            }
        }

    }

    public void removeChildDevice(final String bindingAccount, final String chileDeviceId) throws HomeException {

        gwEngine.removeChildDevice(bindingAccount, chileDeviceId);

    }

    public void removeDevice(final String deviceId) throws HomeException {
        DeviceProxy device = (DeviceProxy) getDeviceById(deviceId);
        if (device == null) {
            device = (DeviceProxy) getDeviceBySerialno(deviceId);
        }

        try {
            removeChildDevice(device.getBindingaccount(), device.getDeviceid());
        } catch (final HomeException e) {

        }

        final List<ZNode> znodes = getAllZNodeByDeviceId(deviceId);
        device.setStates(DeviceStatus.DELETE);

        final List<DeviceEndPoint> endPoints = device.getDeviceEndPoints();
        for (final DeviceEndPoint endPoint : endPoints) {

            ((DeviceEndPointProxy) endPoint).setCurrvalue(DeviceDataTypeKey.Status, DeviceStatus.DELETE.getCode().toString());
            updateEndPoint(endPoint);
        }

        for (final ZNode znode : znodes) {
            if (znode.getParentid() != null) {
                final ZNode currgateway = getZNodeById(znode.getParentid());
                // 同一网关下的设备则逻辑删除 否则物理删除
                if (currgateway != null && znode.getEndPoint() != null && znode.getEndPoint().getDevice().getBindingaccount().equals(currgateway.getDeviceid())) {

                    znode.setStatus(DeviceStatus.DELETE);
                    updateNodeStatus(znode.getZnodeid(), DeviceStatus.DELETE);
                } else {
                    try {
                        deleteZNode(znode.getZnodeid());
                    } catch (final HomeException e) {

                        e.printStackTrace();
                    }
                }
            } else {
                try {
                    deleteZNode(znode.getZnodeid());
                } catch (final HomeException e) {

                    e.printStackTrace();
                }
            }

        }
        updateDevice(device);
    }

    public DeviceEndPoint registerEndPoint(final String sensorieee, final String epieee, final String ep, final Integer sensorType, final String name) throws HomeException {
//
//        final EIDeviceEndPoint defaultPoint = gwEngine.getEndPointByIeee(sensorieee);
//
//        if (defaultPoint != null) {
//            defaultPoint.setEp(ep);
//            final List<String> znodeIds = defaultPoint.getAllZNodeIds();
//            for (final String znodeId : znodeIds) {
//                try {
//                    deleteZNode(znodeId);
//                } catch (final HomeException e) {
//                    e.printStackTrace();
//                }
//            }
//        }


        EIDeviceEndPoint epPoint = gwEngine.getEndPointByIeee(epieee);
        if (epPoint == null) {
            epPoint = gwEngine.registerEndPoint(sensorieee, epieee, ep, sensorType, name);
        }

        final DeviceEndPoint deviceEndPoint = getEndPoint(epPoint.getEndPointId());

        this.fireEndPointEvent(deviceEndPoint, DeviceEndPointEventEnums.createEndPoint);

        return deviceEndPoint;
    }

    public List<Command> gatewayErrorReport(final GatewayErrorReport errorReport) throws HomeException {

        String account = errorReport.getGatewayAccount();


        Device device = null;
        String serialno = errorReport.getSerialno();
        if (serialno != null) {
            if (serialno.length() > 16) {
                serialno = serialno.substring(0, 16);
            }

            try {
                device = HomeServer.getAppEngine().getDeviceById(errorReport.getDeviceId());
            } catch (final HomeException e) {
                e.printStackTrace();
            }

            if (device == null && errorReport.getSerialno() != null) {

                try {
                    device = HomeServer.getAppEngine().getDeviceByIeee(errorReport.getSerialno());

                } catch (final HomeException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (JDSException e) {
                    e.printStackTrace();
                }

                if (device != null) {
                    logger.info("delete: " + device.getDeviceid());
                    gwEngine.deleteGateway(device.getDeviceid());
                }
                if (errorReport.getSerialno() != null && !errorReport.getSerialno().equals("")) {
                    final EIDevice eidevice = gwEngine.createRootDevice(errorReport.getDeviceId(), errorReport.getSerialno(), errorReport.getMacno(), errorReport.getSystemCode(), errorReport.getCurrVersion());
                }

            }

        }

        if (account == null || account.equals("")) {
            account = errorReport.getDeviceId();
        }

        if (account == null || account.equals("")) {
            if (errorReport.getSerialno() != null && !errorReport.getSerialno().equals("")) {
                device = getDeviceBySerialno(errorReport.getSerialno());
                account = device.getDeviceid();

            }
        }

        final OrgManager accountManager = OrgManagerFactory.getOrgManager();

        Person currPerson = null;
        try {
            registerPerson(account, errorReport.getSerialno(), errorReport.getSystemCode());
            currPerson = accountManager.getPersonByAccount(errorReport.getGatewayAccount());
            //
            // EIMsg msg = DbPersonMsgGroupManager.getInstance().createMassSendMsg(currPerson.getID(),
            // MsgType.ERRORREPORT.getType());
            //
            // // EIMsg msg = msgGroup.createMassSendMsg();
            // msg.setType(MsgType.ERRORREPORT.ERRORREPORT.getType());
            // msg.setSendTime(new Date(System.currentTimeMillis()));
            // msg.setReceiver(currPerson.getID());
            // msg.setStatus("NORMAL");
            // msg.setTitle("网关错误报告！");
            // msg.setBody(JSONObject.toJSONString(errorReport).toString());
            //
            // OrgManagerFactory.getOrgManager().updateMsg(msg);

        } catch (final PersonNotFoundException e) {

            registerGateway(errorReport.getDeviceId(), errorReport.getSerialno(), errorReport.getSerialno(), errorReport.getSystemCode(), errorReport.getCurrVersion());

        }

        return gwEngine.gatewayErrorReport(errorReport);

    }

    public void logging(final String account, final String body, final String title) {


        Person currPerson = null;
        try {
            currPerson = OrgManagerFactory.getOrgManager().getPersonByAccount(account);


            MsgClient client = MsgFactroy.getInstance().getClient(currPerson.getID(), MsgType.LOG.getClazz());

            Msg msg = client.creatMsg2Person(currPerson.getID());
            msg.setEventTime(System.currentTimeMillis());
            msg.setStatus(MsgStatus.NORMAL);
            msg.setTitle(title);
            msg.setBody(body);
            client.updateMsg(msg);
            // msgGroup.update();
        } catch (final PersonNotFoundException localPersonNotFoundException) {

        } catch (JDSException e) {
            e.printStackTrace();
        }
    }

    public Gateway activateGateway(final Gateway gateway) throws HomeException {
        final EIDeviceEndPoint endPoint = gwEngine.activateGateway(gateway);
        final EIDevice device = endPoint.getDevice();
        final String accountname = device.getBindingaccount();
        Person account = null;
        // if (orgManager == null) {
        // throw new HomeException("指定厂商不存在", HomeException.USERNAMEONTEXITS);
        // }

        try {
            account = OrgManagerFactory.getOrgManager().getPersonByAccount(accountname);
            if (account == null) {
                throw new HomeException("网关未完成注册！", HomeException.USERNAMEONTEXITS);
            }
        } catch (final PersonNotFoundException e) {

            account = registerPerson(device.getDeviceid(), device.getSerialno(), device.getFactory());

        }

        Person gatewayAccount = null;
        try {
            gatewayAccount = OrgManagerFactory.getOrgManager().getPersonByAccount(device.getBindingaccount());
        } catch (final PersonNotFoundException e1) {
            registerPerson(device.getDeviceid(), device.getSerialno(), device.getFactory());

        }

        final List<EIZNode> nodes = endPoint.getAllZNodes();
        if (nodes.isEmpty()) {
            // 创建家
            final EIPlace place = gwEngine.createPlace(endPoint.getIeeeaddress(), "root", account.getID());
            // 创建默认节点
            final EIZNode znode = gwEngine.createRootZNode(endPoint.getEndPointId(), place.getPlaceid(), account.getID());
        }

        SubSystem subSystem = JDSServer.getClusterClient().getSystem(device.getSubsyscode());

//	serverBean = JDSServer.getAllServerMap().get(device.getSubsyscode());
        //集群节点算法

        OrgManager orgManager = OrgManagerFactory.getOrgManager(ConfigCode.app);

        if (subSystem == null) {

            //    subSystem = orgManager.getSubSystemInfo();
//		subSystem = ((DbOrgManager) OrgManagerFactory.getOrgManager(device.getSubsyscode())).getSubSystemInfo();

        } else {
//	     try {
//	     if (orgManager.getSystemStatus() != -1) {
//	        serverBean = JDSServer.getAllServerMap().get(subSystem.getSysid());
//	     } else {
//
//	     serverBean = ClusterMananerFactory.getClusterManager(subSystem.getSysid()).getSubServer(
//	     orgManager.getPersonByAccount(device.getBindingaccount()).getID(), device.getFactory());
//
//	     }
//
//	     if (serverBean == null) {
//	     serverBean =  ClusterMananerFactory.getClusterManager(orgManager.getSubSystemInfo().getSysid()).getSubServer(
//	     orgManager.getPersonByAccount(device.getBindingaccount()).getID(),
//	     orgManager.getSubSystemInfo().getConfigname());
//	     }
//	     } catch (final PersonNotFoundException e) {
//	     // TODO Auto-generated catch block
//	     e.printStackTrace();
//	     } catch (final InstantiationException e) {
//	     // TODO Auto-generated catch block
//	     e.printStackTrace();
//	     } catch (final IllegalAccessException e) {
//	     // TODO Auto-generated catch block
//	     e.printStackTrace();
//	     } catch (final ClassNotFoundException e) {
//	     // TODO Auto-generated catch block
//	     e.printStackTrace();
//	     }

        }
        // Gateway gateway=new Gateway();
        gateway.setSerialno(device.getSerialno());
        gateway.setMacno(device.getMacaddress());
        gateway.setFactory(device.getFactory());
        gateway.setDeviceId(device.getDeviceid());
//	if (serverBean.getCommandserver()!=null && !serverBean.getCommandserver().equals("")){
//		gateway.setCommandServerUrl(serverBean.getCommandserver() + HomeConstants.SYSTEM_COMMANDSERVERURL);
//	}else{
//		gateway.setCommandServerUrl(serverBean.getUrl() + HomeConstants.SYSTEM_COMMANDSERVERURL);
//	}

//		gateway.setMainServerUrl(serverBean.getUrl());
        // gateway.setGwmServerUrl(subSystem.getMemo());
        gateway.setGatewayAccount(device.getBindingaccount());

        gateway.setKeyword(account.getID());
        logger.info("active返回结果:" + JSONObject.toJSONString(gateway));
        gateway.setCommandServerUrl("http://devcomet.radvev.com" + HomeConstants.SYSTEM_COMMANDSERVERURL);
        gateway.setMainServerUrl("http://devgw.radvev.com");
        return gateway;
    }


    public Area bindingArea(final String sessionieee, final String areaId) throws HomeException {
        Device device = this.getDeviceBySerialno(sessionieee);
        Area area = getAreaById(areaId);

        if (device.getAreaid() != null && device.getAreaid().equals(areaId)) {
            this.fireDeviceEvent(device, DeviceEventEnums.areaUnBind);
        }

        device.setAreaid(areaId);
        device.setPlaceid(area.getPlaceid());
        this.updateDevice(device);


        this.fireDeviceEvent(device, DeviceEventEnums.areaBind);
        return area;
    }

    public Place bindingPlace(final String gwieee, final String placeId) throws HomeException {
        gwEngine.bindingPlace(gwieee, placeId);
        return getPlaceById(placeId);

    }

    public void logout() throws JDSException {

        final String sysCode = JDSActionContext.getActionContext().getSystemCode();
        JDSActionContext.getActionContext().getSession().clear();

        final JDSSessionFactory factory = new JDSSessionFactory(JDSActionContext.getActionContext());
        JDSClientService client = (JDSClientService) JDSActionContext.getActionContext().Par("$JDSC");
        if (client != null) {
            client.disconnect();
        }
        client = factory.getClientService(ConfigCode.app);
        if (client != null) {
            client.disconnect();
        }

    }

    public Person registerPerson(final String accountName, final String sn, final String systemCode) {
        final OrgManager accountManager = OrgManagerFactory.getOrgManager();
        Person account = null;
        try {
            account = accountManager.getPersonByAccount(accountName);
        } catch (final PersonNotFoundException e) {
            accountManager.registerPerson(accountName, sn, systemCode);
        }

        return account;
    }

    public List<ZNode> reSetZNode(final String epId) throws HomeException {

        final DeviceEndPoint ep = getEndPoint(epId);

        final DeviceProxy gatewaydevice = (DeviceProxy) ((DeviceProxy) ep.getDevice()).getRootDevice();
        // 完成节点添加
        final List<ZNode> gatewayznodes = gatewaydevice.getAllZNodes();

        final List<ZNode> znodes = new ArrayList<ZNode>();

        for (final ZNode gateway : gatewayznodes) {

            if (!gateway.getStatus().equals(DeviceStatus.DELETE)) {
                final ZNode currznode = createChildZNode(gateway.getZnodeid(), epId);
                znodes.add(currznode);
            }
        }
        return znodes;
    }

    public Boolean checkOnLine(final String gatewayieee) throws HomeException {
        final Device device = getDeviceBySerialno(gatewayieee);
        final String gwAccount = device.getBindingaccount();
        Person toPerson = null;
        try {
            toPerson = OrgManagerFactory.getOrgManager(ConfigCode.app).getPersonByAccount(gwAccount);
            final ConnectInfo connInfo = new ConnectInfo(toPerson.getID(), toPerson.getAccount(), toPerson.getPassword());
            final Set<JDSSessionHandle> sessionHandleList = JDSServer.getInstance().getSessionHandleList(connInfo);
            if ((sessionHandleList != null) && (sessionHandleList.size() > 0)) {
                return true;
            }
        } catch (final PersonNotFoundException e) {
            throw new HomeException(gatewayieee + " not exit", HomeException.DEVICENOEXITS);
        } catch (final JDSException e) {
            throw new HomeException(e);
        }
        return false;

    }

    public ZNode createChildZNode(final String parentId, final String endPointId) throws HomeException {

        DeviceEndPoint endPoint = this.getEndPoint(endPointId);

        List<ZNode> childnodes = endPoint.getAllZNodes();
        ZNode zNode = null;
        for (ZNode childnode : childnodes) {
            if (childnode != null && childnode.getEndPointid() != null && childnode.getParentid().equals(parentId)) {
                zNode = childnode;
                continue;
            }
        }
        if (zNode == null) {
            final EIZNode znode = gwEngine.createChildZNode(parentId, endPointId);
            zNode = getZNodeById(znode.getZnodeid());
            this.fireZnodeEvent(zNode, ZnodeEventEnums.sensorCreated);
        }
        return zNode;
    }

    public ZNode createGateway(final String serialno, final String personId) throws HomeException {

        final Place place = createPlace(serialno, "root", personId);
        final EIDevice device = gwEngine.getDeviceBySerialno(serialno);
        final Gateway gateway = new Gateway();
        gateway.setDeviceId(device.getDeviceid());
        gateway.setSerialno(serialno);

        final EIDeviceEndPoint endPoint = gwEngine.activateGateway(gateway);
        final ZNode znode = createRootZNode(endPoint.getEndPointId(), place.getPlaceid(), personId);

        return znode;

    }

    public ZNode createRootZNode(final String endpointid, final String placeId, final String createuiserid, ZNodeZType type) throws HomeException {
        final EIZNode znode = gwEngine.createRootZNode(endpointid, placeId, createuiserid, type);
        return getZNodeById(znode.getZnodeid());
    }

    public ZNode createRootZNode(final String endpointid, final String placeId, final String createuiserid) throws HomeException {

        final EIZNode znode = gwEngine.createRootZNode(endpointid, placeId, createuiserid);
        return getZNodeById(znode.getZnodeid());
    }

    public Device createDevice(final String serialno, final String macaddress, final Integer type, final String factory, final String bindingAccount) throws HomeException {


        final EIDevice eidevice = gwEngine.createDevice(serialno, macaddress, type, factory, bindingAccount);

        Device device = this.getDeviceById(eidevice.getDeviceid());

        fireDeviceEvent(device, DeviceEventEnums.register);
        return device;
    }

    public List<ZNode> findZNodesByCreateId(final String userId, final Integer sensorType) throws HomeException {

        final List<EIZNode> znodes = gwEngine.findZNodesByCreateId(userId);
        final List<ZNode> cnodes = new ArrayList<ZNode>();

        for (final EIZNode znode : znodes) {
            if (znode == null) {
                cnodes.add(getZNodeById(znode.getZnodeid()));
            } else if (znode != null && znode.getZtype() != null && znode.getZtype().equals(sensorType)) {
                cnodes.add(getZNodeById(znode.getZnodeid()));
            }
        }

        return cnodes;
    }

    public ZNode findZNodeGWSerialno(final String ieee, final Integer sensorType) throws HomeException {

        final Device device = getDeviceBySerialno(ieee);

        Person person = null;
        try {
            person = OrgManagerFactory.getOrgManager().getPersonByAccount(device.getBindingaccount());
        } catch (final PersonNotFoundException e) {
            throw new HomeException();
        }

        Person appperson = null;
        try {
            appperson = OrgManagerFactory.getOrgManager().getPersonByAccount(device.getAppaccount());
        } catch (final PersonNotFoundException e) {
            throw new HomeException();
        }

        final List<Device> dbDevices = getDeviceByBindAccount(device.getBindingaccount());

        for (final Device cdevice : dbDevices) {
            if (cdevice.getDevicetype().equals(sensorType)) {
                final List<ZNode> znodes = getAllZNodeByDeviceId(cdevice.getDeviceid(), appperson.getID());
                if (znodes.size() > 0) {
                    return znodes.get(0);
                }
            }

        }
        return null;
    }

    public List<Sensortype> getAllSensorType() throws HomeException {
        final List<Sensortype> types = new ArrayList<Sensortype>();

        final Set<Integer> sensorTypeIds = gwEngine.getSensoTypesByBatch();

        for (final Integer sensorTypeId : sensorTypeIds) {

            types.add(getSensorTypesByNo(sensorTypeId));
        }
        return types;
    }

    public List<Sensortype> getSensorTypesByGatewayId(final String gatewayId) throws HomeException {
        final List<Sensortype> types = new ArrayList<Sensortype>();

        String batch = gwEngine.getDeviceByNodeId(gatewayId).getBatch();

        if ((batch == null) || (batch.equals(""))) {
            batch = "default";
        }
        final Set<Integer> sensorTypeIds = gwEngine.getSensoTypesByBatch(batch);
        for (final Integer sensorTypeId : sensorTypeIds) {

            types.add(getSensorTypesByNo(sensorTypeId));
        }
        return types;
    }

    public ZNode copyGateway(final String sourceNodeId, final String userID, final ZNodeZType type, final String placeId) throws HomeException {

        final String znodeId = gwEngine.copyGateway(sourceNodeId, userID, type, placeId).getZnodeid();
        return getZNodeById(znodeId);
    }


    public List<Place> getChildPlaces(final String placeid) {
        final List<Place> palces = new ArrayList<Place>();

        final List<String> childs = gwEngine.findAllChildPlaceIds(placeid);
        for (final String childId : childs) {
            try {
                palces.add(getPlaceById(childId));
            } catch (final HomeException e) {
                e.printStackTrace();
            }

        }
        return palces;
    }

    public Device createRootDevice(String deviceId, String serialno, String macno, String systemCode, String currVersion) throws HomeException {
        EIDevice eidevice = this.gwEngine.createRootDevice(deviceId, serialno, macno, systemCode, currVersion);

        return this.getDeviceById(eidevice.getDeviceid());

    }


    public ListResultModel<Set<String>> findPlace(Condition<HomeConditionKey, JLuceneIndex> condition) {
        return gwEngine.findPlace(condition);
    }

    ;

    public ListResultModel<Set<String>> findArea(Condition<HomeConditionKey, JLuceneIndex> condition) {
        return gwEngine.findArea(condition);
    }

    ;

    public ListResultModel<Set<String>> findDevice(Condition<IOTConditionKey, JLuceneIndex> condition) {
        return gwEngine.findDevice(condition);
    }

    ;

    public ListResultModel<Set<String>> findEndPoint(Condition<IOTConditionKey, JLuceneIndex> condition) {
        return gwEngine.findEndPoint(condition);
    }

    ;

    public ListResultModel<Set<String>> findZNode(Condition<IOTConditionKey, JLuceneIndex> condition) {
        return gwEngine.findZNode(condition);
    }

    ;

    public ListResultModel<Set<String>> findAlarm(Condition<HomeConditionKey, JLuceneIndex> condition) {
        return gwEngine.findAlarm(condition);
    }

    ;

    public ListResultModel<Set<String>> findScene(Condition<HomeConditionKey, JLuceneIndex> condition) {
        return gwEngine.findScene(condition);
    }

    ;

    public Set<String> findGWDevicesByFactory(String factoryName) {

        final Set<String> deviceIdList = gwEngine.findGWDevicesByFactory(factoryName);
        return deviceIdList;


    }

    private void fireSensorEvent(final ZNode sensor, final SensorEventEnums eventID) throws HomeException {
        Map context = new HashMap();
        fireSensorEvent(sensor, eventID, context);
    }

    private void fireZnodeEvent(final ZNode sensor, final ZnodeEventEnums eventID) throws HomeException {
        Map context = new HashMap();
        fireZnodeEvent(sensor, eventID, context);
    }

    private void fireZnodeEvent(final ZNode znode, final ZnodeEventEnums eventID, Map eventContext) throws HomeException {

        ZNodeEvent event = new ZNodeEvent(znode, null, eventID, null);
        event.setContextMap(eventContext);
        try {
            HomeEventControl.getInstance().dispatchEvent(event);
        } catch (final JDSException e) {
            throw new HomeException(e);
        }
    }

    private void fireSensorEvent(final ZNode znode, final SensorEventEnums eventID, Map eventContext) throws HomeException {
        Map context = new HashMap();
        SensorEvent event = new SensorEvent(znode, null, eventID, null);
        event.setContextMap(eventContext);
        try {
            HomeEventControl.getInstance().dispatchEvent(event);
        } catch (final JDSException e) {
            throw new HomeException(e);
        }
    }


    private void fireDeviceEvent(Device device, DeviceEventEnums eventID) throws HomeException {
        Map context = new HashMap();
        fireDeviceEvent(device, eventID, context);
    }

    private void fireDeviceEvent(Device device, DeviceEventEnums eventID, Map eventContext) throws HomeException {
        DeviceEvent event = new DeviceEvent(device, null, eventID, null);
        event.setContextMap(eventContext);
        try {
            HomeEventControl.getInstance().dispatchEvent(event);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    private void fireEndPointEvent(DeviceEndPoint endPoint, DeviceEndPointEventEnums eventID) throws HomeException {
        Map context = new HashMap();
        fireEndPointEvent(endPoint, eventID, context);
    }


    private void fireEndPointEvent(DeviceEndPoint endPoint, DeviceEndPointEventEnums eventID, Map eventContext) throws HomeException {

        DeviceEndPointEvent event = new DeviceEndPointEvent(endPoint, null, eventID, null);

        event.setContextMap(eventContext);
        try {
            HomeEventControl.getInstance().dispatchEvent(event);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void updateSensorType(Sensortype sensortype) throws HomeException {
        gwEngine.updateSensorType(sensortype);
    }

    public void deleteSensorType(Integer typeno) throws HomeException {
        gwEngine.deleteSensorType(typeno);
    }
}
